home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Windows Expert
/
Windows Expert.iso
/
desktop
/
spinner.zip
/
SPINPLT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-05-20
|
6KB
|
235 lines
//
// SPINPLT - spinning rainbow SPX plotting functions
//
// Version 1.0 10/04/91 Copyright (C) 1991 Lantern Corp.
// Author: Edward Hutchins
// Revisions:
//
#include "spinner.h"
//
// defines
//
#define p1 Pt[0]
#define x1 (Pt[0].x)
#define y1 (Pt[0].y)
#define p2 Pt[1]
#define x2 (Pt[1].x)
#define y2 (Pt[1].y)
#define p2o Pt[2]
#define x2o (Pt[2].x)
#define y2o (Pt[2].y)
#define p1o Pt[3]
#define x1o (Pt[3].x)
#define y1o (Pt[3].y)
#define nR rgbC[0]
#define nG rgbC[1]
#define nB rgbC[2]
#define nRd rgbCd[0]
#define nGd rgbCd[1]
#define nBd rgbCd[2]
#define newd() ((arand( 10 )) + 3)
#define negd(d) ((d)=(((d)<0) ? newd():-newd()))
#define randsgn() (arand( 2 ) ? 1 : -1)
#define randpos(d) (arand( (d) - 40 ) + 20)
#define randcolor() arand(256)
//
// imports
//
IMPORT HANDLE hLibInst FROM( spinner.c );
IMPORT INT nColorCnt FROM( spinner.c );
IMPORT BOOL bEnabled FROM( spinner.c );
IMPORT TRI triBlank FROM( spinner.c );
IMPORT TRI triSpin FROM( spinner.c );
IMPORT TRI triSolid FROM( spinner.c );
//
// locals
//
LOCAL DWORD dwSeed;
//
// arand - pseudorandom number from 0 to x-1
//
INT NEAR PASCAL arand( INT x )
{
dwSeed = dwSeed * 0x343fd + 0x269ec3;
return( (INT)(((dwSeed >> 16) & 0x7fff) * x >> 15) );
}
//
// Tri - convert a tri-state into a boolean (unset == random)
//
BOOL NEAR PASCAL Tri( TRI tri )
{
switch (tri)
{
case TRI_FALSE:
return( FALSE );
case TRI_TRUE:
return( TRUE );
default:
return( (BOOL)arand( 2 ) );
}
}
//
// AllocPalette - allocate the logical palette
//
HPALETTE NEAR PASCAL AllocPalette( INT nSize )
{
NPLOGPALETTE npLogPalette;
HPALETTE hPalette;
INT t;
npLogPalette = (NPLOGPALETTE)LocalAlloc( LPTR, sizeof(LOGPALETTE) +
sizeof(PALETTEENTRY) * nSize );
if (!npLogPalette) return( FALSE );
npLogPalette->palVersion = 0x0300;
npLogPalette->palNumEntries = nSize;
for (t = 0; t < nSize; ++t)
{
npLogPalette->palPalEntry[t].peRed =
npLogPalette->palPalEntry[t].peGreen =
npLogPalette->palPalEntry[t].peBlue = (BYTE)((t * 256) / nSize);
npLogPalette->palPalEntry[t].peFlags = PC_RESERVED;
}
hPalette = CreatePalette( npLogPalette );
LocalFree( (HANDLE)npLogPalette );
return( hPalette );
}
//
// SaverDraw - the main drawing routine
//
VOID FAR PASCAL EXPORT SaverDraw( HWND hwnd, HDC hdc, HANDLE hinst,
BOOL (FAR PASCAL *yieldproc)( VOID ) )
{
INT xClient, yClient;
INT x1d, y1d, x2d, y2d;
POINT Pt[4];
INT nCurPalEntry;
INT rgbC[3], rgbCd[3];
HPALETTE hAppPalette, hOldPalette;
BOOL bSpin;
BOOL bSolid;
RECT rect;
dwSeed += GetTickCount();
GetWindowRect( hwnd, &rect );
xClient = rect.right - rect.left;
yClient = rect.bottom - rect.top;
if (Tri( triBlank )) FillRect( hdc, &rect, GetStockObject( BLACK_BRUSH ) );
bSpin = Tri( triSpin );
bSolid = Tri( triSolid );
hAppPalette = AllocPalette( nColorCnt );
hOldPalette = SelectPalette( hdc, hAppPalette, FALSE );
nCurPalEntry = 0;
x1 = randpos( xClient ); x1d = newd() * randsgn();
x2 = randpos( xClient ); x2d = newd() * randsgn();
y1 = randpos( yClient ); y1d = newd() * randsgn();
y2 = randpos( yClient ); y2d = newd() * randsgn();
nR = randcolor(); nRd = newd() * randsgn();
nG = randcolor(); nGd = newd() * randsgn();
nB = randcolor(); nBd = newd() * randsgn();
while ((*yieldproc)())
{
INT t;
PALETTEENTRY PalEntry;
// save the old coordinates
p1o = p1; p2o = p2;
// advance the points
x1 += x1d; y1 += y1d;
x2 += x2d; y2 += y2d;
// check the bounds
if (x1 < 0 || x1 > xClient) { x1 -= x1d; negd( x1d ); x1 += x1d; }
if (x2 < 0 || x2 > xClient) { x2 -= x2d; negd( x2d ); x2 += x2d; }
if (y1 < 0 || y1 > yClient) { y1 -= y1d; negd( y1d ); y1 += y1d; }
if (y2 < 0 || y2 > yClient) { y2 -= y2d; negd( y2d ); y2 += y2d; }
// spin as needed
if (bSpin)
{
INT nDx = x2 - x1, nDy = y2 - y1;
INT dx = ((nDx < 0) ? -nDx : nDx);
INT dy = ((nDy < 0) ? -nDy : nDy);
INT nDist = dx + dy - (((dx > dy) ? dy : dx) >> 1);
if (nDist > 1)
{
INT ddx = nDx * 2 / nDist;
INT ddy = nDy * 2 / nDist;
x1d += ddx, x2d -= ddx;
y1d += ddy, y2d -= ddy;
}
}
// change the colors one component at a time
t = arand( 3 );
rgbC[t] += rgbCd[t];
if (rgbC[t] < 0 || rgbC[t] > 255)
{
rgbC[t] -= rgbCd[t];
negd( rgbCd[t] );
rgbC[t] += rgbCd[t];
}
// put the color into the current palette entry
PalEntry.peRed = (BYTE)nR;
PalEntry.peGreen = (BYTE)nG;
PalEntry.peBlue = (BYTE)nB;
PalEntry.peFlags = PC_RESERVED;
RealizePalette( hdc );
AnimatePalette( hAppPalette, nCurPalEntry, 1, &PalEntry );
if (bSolid)
{
HBRUSH hBrush;
hBrush = CreateSolidBrush( PALETTEINDEX(nCurPalEntry) );
hBrush = SelectObject( hdc, hBrush );
SelectObject( hdc, GetStockObject( NULL_PEN ) );
SetPolyFillMode( hdc, ALTERNATE );
Polygon( hdc, Pt, 4 );
hBrush = SelectObject( hdc, hBrush );
DeleteObject( hBrush );
}
else // line segments
{
HPEN hPen;
hPen = CreatePen( PS_SOLID, 0, PALETTEINDEX(nCurPalEntry) );
hPen = SelectObject( hdc, hPen );
MoveTo( hdc, x1, y1 );
LineTo( hdc, x2, y2 );
hPen = SelectObject( hdc, hPen );
DeleteObject( hPen );
}
// use the next palette entry next time
if (++nCurPalEntry >= nColorCnt) nCurPalEntry = 0;
}
DeleteObject( SelectPalette( hdc, hOldPalette, FALSE ) );
}